const { Service } = require('egg')
const { tableToList } = require('../utils/tools')

module.exports = class GradeService extends Service {
  /**
   * * 课程成绩查询
   * @param {String} term 学期
   * @return {Array} *
   */
  async table(term) {
    const Cookie = this.ctx.state.Cookie
    const apiUrl = 'http://csujwc.its.csu.edu.cn/jsxsd/kscj/cjcx_list'
    const res = await this.ctx.curl(apiUrl, {
      method: 'POST',
      data: {
        xnxq01id: term,
      },
      headers: {
        Cookie,
        'Content-Type': 'application/x-www-form-urlencoded',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
      },
      timeout: 10000,
    })
    // console.log('res.status', res.status);
    // 空  序号 初修学期 获得学期 课程 成绩 学分 课程属性 课程性质 获得方式
    const header = ['课程名称', '类型', '学分', '成绩', '考核方式', '课程性质'] // 列名称
    if (res.status === 200) {
      try {
        const cb = (cell, rowIndex, colIndex) => {
          const value = cell.text().trim().replace(/\s/g, '') // 获取单元格内容
          // console.log('value', value)
          if (rowIndex > 0 && colIndex === 5) { // 成绩一列单独处理，提取出详情占比链接
            // console.log('cell.children()[0]', cell.children()[0].attribs.href.split('/')[1])
            const link = `http://csujwc.its.csu.edu.cn${cell.children()[0].attribs.href.split('\'')[1]}`
            return [value, link]
          }
          return value
        }

        const tableList = tableToList(res.data.toString(), '#dataList', '', cb)
        /* [ '','序号', '初修学期', '获得学期', '课程', '成绩', '学分', '课程属性', '课程性质', '获得方式' ]; */

        const columnNeed = [4, 7, 6, 5, 9, 8] // 需要提取的列序号
        if (tableList.length === 0 || tableList[1][0] === '未查询到数据') return { table: {}, header }

        /* 获取成绩占比 */
        const P = []
        for (let i = 0; i * 2 + 1 < tableList.length; i++) {
          const di = i * 2 + 1
          P.push(this.proportion(tableList[di][5][1]))
        }
        const resAll = await Promise.all(P)
        for (let i = 0; i * 2 + 1 < tableList.length; i++) {
          const di = i * 2 + 1
          tableList[di][5][1] = resAll[i]
        }
        /* end */

        const info = {}
        for (let i = 0; i * 2 + 1 < tableList.length; i++) {
          const di = i * 2 + 1
          const term_ = tableList[di][2]
          if ((term_ in info) === false) { info[term_] = [] }
          const tem = []
          columnNeed.forEach((idx) => {
            if (idx === 5) { tem.push({ score: tableList[di][idx][0], from: tableList[di][idx][1] }) }
            else if (idx === 4) { tem.push(tableList[di][idx].replace(/^\[.*?\]/, '')) }
            else { tem.push(tableList[di][idx]) }
          })
          info[term_].push(tem)
        }

        return { table: info, header }
      } catch (err) {
        console.log('err', err)
        throw err
      }
    }
    return { table: {}, header }
  }

  /**
   * * 成绩占比数据请求
   * @param {string} fromLink 占比详情请求地址
   * @return {object} *
   */
  async proportion(fromLink) {
    if (!fromLink) return []
    const Cookie = this.ctx.state.Cookie
    const apiUrl = encodeURI(fromLink)
    const res = await this.ctx.curl(apiUrl, {
      method: 'GET',
      headers: {
        Cookie,
        'Content-Type': 'application/x-www-form-urlencoded',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
      },
      timeout: 10000,
    })
    if (res.status === 200) {
      try {
        const tableList = tableToList(res.data.toString(), '#dataList')
        const Ntable = []
        if (tableList.length > 1) {
          for (let i = 1; i + 1 < tableList[0].length - 1; i += 2) {
            const type = tableList[0][i]
            const score = tableList[1][i]
            const proportion = tableList[1][i + 1]
            if (!proportion || proportion === '0%') continue
            Ntable.push({ type, score, proportion })
          }
        }
        return Ntable
      } catch (err) {
        console.log('err', err)
        throw err
      }
    }
    return []
  }
}
